/*
 * CMediaCasterManager.cpp
 *
 *  Created on: 2016-6-21
 *      Author: terry
 */

#include "CMediaCasterManager.h"
#include "TcpMediaCasterServer.h"
#include "MediaCasterTable.h"
#include "CMediaCaster.h"
#include "TSingleton.h"
#include "UdtMediaCasterServer.h"
#include "TMediaCasterServer.h"
#include "UmsgMediaCasterServer.h"


namespace av
{

typedef comn::Singleton< CMediaCasterManager >	CMediaCasterManagerSingleton;

static bool s_startup = false;


CMediaCasterManager& CMediaCasterManager::instance()
{
	if (!s_startup)
	{
		Startup();
	}
	return CMediaCasterManagerSingleton::instance();
}

void CMediaCasterManager::Startup()
{
	TcpServer::Startup();
	UdtMediaCasterServer::Startup();

	s_startup = true;
}

void CMediaCasterManager::Cleanup()
{
	TcpServer::Cleanup();
	UdtMediaCasterServer::Cleanup();

	s_startup = false;
}

CMediaCasterManager::CMediaCasterManager():
		m_sink(),
		m_tcpServer(new TMediaCasterServer()),
        m_udtServer(new UdtMediaCasterServer()),
		m_tcp2Server(new TcpMediaCasterServer()),
        m_msgServer(new UmsgMediaCasterServer())
{
    m_tcpServer->setEventSink(this);
    m_udtServer->setEventSink(this);
    m_tcp2Server->setEventSink(this);
    m_msgServer->setEventSink(this);
}

CMediaCasterManager::~CMediaCasterManager()
{
	stopAll();
}

bool CMediaCasterManager::start(int protocol, const char* ip, int port, const std::string& params)
{
	bool done = false;
	MediaCasterServerPtr server = getServer(protocol);
	if (server)
	{
		done = server->start(ip, port, params);
	}
	return done;
}

bool CMediaCasterManager::isStarted(int protocol)
{
	MediaCasterServerPtr server = getServer(protocol);
	if (server)
	{
		return server->isStarted();
	}
	return false;
}

void CMediaCasterManager::stop(int protocol)
{
	MediaCasterServerPtr server = getServer(protocol);
	if (server)
	{
		server->stop();
	}
    
}

void CMediaCasterManager::stopAll()
{
	m_tcpServer->stop();
    m_udtServer->stop();
    m_tcp2Server->stop();
    m_msgServer->stop();
}

MediaCasterPtr CMediaCasterManager::open(const char* name, const MediaFormat& fmt)
{
	CMediaCasterPtr caster(new CMediaCaster());
	if (caster->open(name, std::string()) == 0 && caster->setFormat(fmt))
	{
		MediaCasterTable::instance().put(name, caster);
	}
	else
	{
		caster.reset();
	}
	return caster;
}

void CMediaCasterManager::close(const char* name)
{
	m_tcpServer->close(name);
    m_udtServer->close(name);
    m_tcp2Server->close(name);
    m_msgServer->close(name);

	MediaCasterTable::instance().remove(name);
}

MediaCasterPtr CMediaCasterManager::find(const char* name)
{
	CMediaCasterPtr caster;
	MediaCasterTable::instance().find(name, caster);
	return caster;
}

void CMediaCasterManager::closeAll()
{
	m_tcpServer->closeAll();
    m_udtServer->closeAll();
    m_tcp2Server->closeAll();
    m_msgServer->closeAll();

	MediaCasterTable::instance().clear();
}

void CMediaCasterManager::setEventSink(MediaCasterEventSink* sink)
{
	comn::AutoCritSec	lock(m_cs);
	m_sink = sink;
}

MediaCasterServerPtr CMediaCasterManager::getServer(int protocol)
{
	if (protocol == kTcpCaster)
	{
		return m_tcpServer;
	}
    else if (protocol == kUdtCaster)
    {
        return m_udtServer;
    }
    else if (protocol == kMtpCaster)
	{
		return m_tcp2Server;
	}
    else if (protocol == kUmsgCaster)
    {
    	return m_msgServer;
    }

	return MediaCasterServerPtr();
}

void CMediaCasterManager::onCasterEvent(MediaCasterEvent& event, int protocol)
{
    if (m_sink)
    {
        m_sink->onCasterEvent(event, protocol);
    }
}



} /* namespace av */
